using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using OpenComposite.EII.Repository;
using WeifenLuo.WinFormsUI.Docking;
using System.Xml;
using System.IO;
using OpenComposite.Base.Collections;

namespace OpenComposite.EII.Designer.SCA
{
	public partial class FormShowCapabilities : DockContent
	{
		#region Initialization
		public FormShowCapabilities(ServiceModule svcModule)
		{
			_svcModule = svcModule;
			_verbs = null;
			_serviceProvider = null;

			InitializeComponent();

			init();
		}
		public FormShowCapabilities(IServiceProvider serviceProvider, BindingListEx<Verb> verbs)
		{
			_svcModule = null;
			_verbs = verbs;
			_serviceProvider = serviceProvider;

			InitializeComponent();

			init();
		}
		private void init()
		{
			this.DialogResult = DialogResult.Cancel;

			this.StartPosition = FormStartPosition.CenterScreen;
			this.DockAreas = DockAreas.Float;
			this.ShowHint = DockState.Float;
			this.TabText = "Capabilities";

			dgvVerbs.AutoGenerateColumns = false;
			displayVerbs();
		}
		#endregion

		#region Public Members

		#region Events
		public event EventHandler VerbsChanged = null;
		#endregion

		#region Properties
		public bool ReadOnly
		{
			get { return _bReadonly; }
			set {
				if ( _bReadonly != value ) {
					_bReadonly = value;
					dgvVerbs.AllowDrop = !_bReadonly;
					tsbtnAddNewCapMeth.Visible = !_bReadonly;
				}
			}
		}

		public ServiceModule ServiceModule
		{
			get { return _svcModule; }
			set {
				_svcModule = value;
				displayVerbs();
			}
		}
		public BindingListEx<Verb> Verbs
		{
			get { return _verbs; }
			set {
				_verbs = value;
				displayVerbs();
			}
		}
		#endregion

		#region Methods
		#endregion

		#endregion

		#region Protected Members

		protected override object GetService(Type serviceType)
		{
			if ( _svcModule != null ) {
				return _svcModule.GetService(serviceType);
			} else if ( _serviceProvider != null ) {
				return _serviceProvider.GetService(serviceType);
			} else {
				return null;
			}
		}

		protected void OnVerbsChanged()
		{
			EventHandler tmp = this.VerbsChanged;
			if ( tmp != null ) {
				tmp(this, EventArgs.Empty);
			}
		}
		#endregion

		#region Private Members

		#region Variables
		private bool _bReadonly = false;
		private BindingListEx<Verb> _verbs = null;
		private ServiceModule _svcModule = null;
		private IServiceProvider _serviceProvider = null;
		#endregion

		#region Methods
		private void displayVerbs()
		{
			dgvVerbs.DataSource = null;
			if ( _svcModule != null ) {
				dgvVerbs.DataSource = _svcModule.GetVerbs();
			} else {
				dgvVerbs.DataSource = _verbs;
			}
		}
		#endregion

		#region Event Handler
		private void dgvVerbs_CellContentClick(object sender, DataGridViewCellEventArgs e)
		{
			if ( (e.ColumnIndex != colInputXsd.Index && e.ColumnIndex != colOutputXsd.Index )
				 || e.RowIndex < 0 )
				return;

			formXmlViewer frmXml = new formXmlViewer();
			Verb verb = dgvVerbs.Rows[e.RowIndex].DataBoundItem as Verb;
			if ( verb == null ) return;
			XmlDocument xd = new XmlDocument();
			XmlWriterSettings settings = new XmlWriterSettings();
			settings.OmitXmlDeclaration = true;
			if ( e.ColumnIndex == colInputXsd.Index && verb.InputBusinessObject != null ) {
				// Input Schema column
				xd.LoadXml(verb.InputBusinessObject.SchemaString);
			} else if ( e.ColumnIndex == colOutputXsd.Index && verb.OutputBusinessObject != null ) {
				// Output Schema column
				xd.LoadXml(verb.OutputBusinessObject.SchemaString);
			}
			frmXml.XmlDocument = xd;
			frmXml.ShowDialog();
		}

		#region Drag & Drop
		private void dgvVerbs_DragDrop(object sender, DragEventArgs e)
		{
			TreeNode tn = e.Data.GetData(typeof(TreeNode)) as TreeNode;
			// if not dragging an TreeNode object from the repository tree
			if ( tn == null ) {
				// drop not allowed
				e.Effect = DragDropEffects.None;
				return;
			}
			BusinessObject bo = tn.Tag as BusinessObject;
			if ( bo == null ) {
				// drop not allowed
				e.Effect = DragDropEffects.None;
				return;
			}
			Point ptClient = dgvVerbs.PointToClient(new Point(e.X, e.Y));
			DataGridView.HitTestInfo hti = dgvVerbs.HitTest(ptClient.X, ptClient.Y);
			Verb verb = dgvVerbs.Rows[hti.RowIndex].DataBoundItem as Verb;
			if ( verb == null ) return;
			// mouse over 'Input Schema' or 'Output Schema' column?
			if ( hti.Type == DataGridViewHitTestType.Cell ) {
				if ( hti.ColumnIndex == colInputXsd.Index ) {
					verb.InputBusinessObject = bo;
					dgvVerbs.UpdateCellValue(hti.ColumnIndex, hti.RowIndex);
				} else if ( hti.ColumnIndex == colOutputXsd.Index ) {
					verb.OutputBusinessObject = bo;
					dgvVerbs.UpdateCellValue(hti.ColumnIndex, hti.RowIndex);
				}
			}
		}

		private void dgvCapMethods_DragEnter(object sender, DragEventArgs e)
		{

		}

		private void dgvVerbs_DragLeave(object sender, EventArgs e)
		{

		}

		private void dgvVerbs_DragOver(object sender, DragEventArgs e)
		{
			TreeNode tn = e.Data.GetData(typeof(TreeNode)) as TreeNode;
			// mouse over 'Input Schema' or 'Output Schema' column?
			if ( tn == null ) {
				// drop not allowed
				e.Effect = DragDropEffects.None;
				return;
			}
			BusinessObject bo = tn.Tag as BusinessObject;
			if ( bo == null ) {
				// drop not allowed
				e.Effect = DragDropEffects.None;
				return;
			}
			Point ptClient = dgvVerbs.PointToClient(new Point(e.X, e.Y));
			DataGridView.HitTestInfo hti = dgvVerbs.HitTest(ptClient.X, ptClient.Y);
			// mouse over 'Input Schema' or 'Output Schema' column?
			if ( hti.Type == DataGridViewHitTestType.Cell &&
				 ( hti.ColumnIndex == colInputXsd.Index || hti.ColumnIndex == colOutputXsd.Index ) ) {
				e.Effect = DragDropEffects.Move;
			} else {
				e.Effect = DragDropEffects.None;
			}
		}

		private void dgvVerbs_GiveFeedback(object sender, GiveFeedbackEventArgs e)
		{

		}

		private void dgvVerbs_QueryContinueDrag(object sender, QueryContinueDragEventArgs e)
		{

		}
		#endregion

		private void contextMain_Opening(object sender, CancelEventArgs e)
		{
			if ( this.ReadOnly )
				e.Cancel = true;
		}
		private void dgvVerbs_MouseDown(object sender, MouseEventArgs e)
		{
		}

		private void tsmiAddNewVerb_Click(object sender, EventArgs e)
		{
			RepositoryService repSvc = (RepositoryService)this.GetService(typeof(RepositoryService));
			if ( repSvc == null ) throw new NullReferenceException("RepositoryService not available.");

			bool isSaveContinue;
			do {
				IRepositoryItem parentItem = _svcModule;
				Verb verb = repSvc.GetNewItem<Verb>(true, ref parentItem, out isSaveContinue);
				if ( verb != null ){
					Global.Data.AddRepositoryHierarchy(_svcModule, verb, Global.Status.CurrentRepositoryId);
				}
			} while ( isSaveContinue );
			displayVerbs();
			OnVerbsChanged();
		}
		private void tsmiDeleteVerb_Click(object sender, EventArgs e)
		{
			OnVerbsChanged();
		}

		private void tsbtnOK_Click(object sender, EventArgs e)
		{
			this.DialogResult = DialogResult.OK;
			this.Close();
		}

		#endregion

		#endregion
	}
}